package apps

import (
	"encoding/json"
	"errors"
	"fmt"

	"gitee.com/littletow/qywx/services/commons"
)

// 自建应用自定义菜单接口
const (
	CreateMenuURL string = "https://qyapi.weixin.qq.com/cgi-bin/menu/create"
	GetMenuURL    string = "https://qyapi.weixin.qq.com/cgi-bin/menu/get"
	DeleteMenuURL string = "https://qyapi.weixin.qq.com/cgi-bin/menu/delete"
)

type MenuType string

// 自定义菜单接口可实现多种类型按钮，枚举
const (
	Click           MenuType = "click"              // 点击推事件
	View            MenuType = "view"               // 跳转URL
	ScancodePush    MenuType = "scancode_push"      // 扫码推事件
	ScancodeWaitMsg MenuType = "scancode_waitmsg"   // 扫码推事件 且弹出“消息接收中”提示框
	PicSysPhoto     MenuType = "pic_sysphoto"       // 弹出系统拍照发图
	PicPhotoOrAlbum MenuType = "pic_photo_or_album" // 弹出拍照或者相册发图
	PicWeixin       MenuType = "pic_weixin"         // 弹出企业微信相册发图器
	LocationSelect  MenuType = "location_select"    // 弹出地理位置选择器
	ViewMiniProgram MenuType = "view_miniprogram"   // 跳转到小程序
)

// CreateMenuReq 创建菜单参数请求
type CreateMenuReq struct {
	Button []ButtonItem `json:"button"`
}

// GetMenuResp 获取菜单响应
type GetMenuResp struct {
	commons.CommonError
	Button []ButtonItem `json:"button"`
}

// ButtonItem 菜单选项
type ButtonItem struct {
	Type      MenuType     `json:"type,omitempty"`       // 菜单的响应动作类型
	Name      string       `json:"name"`                 // 菜单的名字。不能为空，主菜单不能超过16字节，子菜单不能超过40字节。
	Key       string       `json:"key,omitempty"`        // 菜单KEY值，用于消息接口推送，不超过128字节
	Url       string       `json:"url,omitempty"`        // 网页链接，成员点击菜单可打开链接，不超过1024字节。为了提高安全性，建议使用https的url
	PagePath  string       `json:"pagepath,omitempty"`   // 小程序的页面路径
	AppID     string       `json:"appid,omitempty"`      // 小程序的appid（仅与企业绑定的小程序可配置）
	SubButton []ButtonItem `json:"sub_button,omitempty"` // 二级菜单数组，个数应为1~5个
}

// CreateMenu 创建菜单
// 参考 https://open.work.weixin.qq.com/api/doc/90000/90135/90231
func (manager *CustomAppManager) CreateMenu(req CreateMenuReq, agentid string) (*commons.CommonError, error) {
	if agentid == "" {
		return nil, errors.New(commons.ErrParamInValid)
	}
	token, err := manager.getToken()
	if err != nil {
		return nil, err
	}

	url := fmt.Sprintf("%s?access_token=%s&agentid=%s", CreateMenuURL, token, agentid)

	var body []byte
	body, err = commons.PostJSON(url, req)
	if err != nil {
		return nil, err
	}
	var resp commons.CommonError
	err = json.Unmarshal(body, &resp)
	if err != nil {
		return nil, err
	}
	// 出错返回码，为0表示成功，非0表示调用失败
	if resp.ErrCode != 0 {
		err = fmt.Errorf("CreateMenu error : errcode=%v , errormsg=%v", resp.ErrCode, resp.ErrMsg)
		return nil, err
	}
	return &resp, nil
}

// GetMenu 获取菜单
// 参考 https://open.work.weixin.qq.com/api/doc/90000/90135/90232
func (manager *CustomAppManager) GetMenu(agentid string) (*GetMenuResp, error) {
	if agentid == "" {
		return nil, errors.New(commons.ErrParamInValid)
	}
	token, err := manager.getToken()
	if err != nil {
		return nil, err
	}

	url := fmt.Sprintf("%s?access_token=%s&agentid=%s", CreateMenuURL, token, agentid)

	var body []byte
	body, err = commons.HTTPGet(url)
	if err != nil {
		return nil, err
	}
	var resp GetMenuResp
	err = json.Unmarshal(body, &resp)
	if err != nil {
		return nil, err
	}
	// 出错返回码，为0表示成功，非0表示调用失败
	if resp.ErrCode != 0 {
		err = fmt.Errorf("GetMenu error : errcode=%v , errormsg=%v", resp.ErrCode, resp.ErrMsg)
		return nil, err
	}
	return &resp, nil
}

// DeleteMenu 删除菜单
// 参考 https://open.work.weixin.qq.com/api/doc/90000/90135/90233
func (manager *CustomAppManager) DeleteMenu(agentid string) (*commons.CommonError, error) {
	if agentid == "" {
		return nil, errors.New(commons.ErrParamInValid)
	}
	token, err := manager.getToken()
	if err != nil {
		return nil, err
	}

	url := fmt.Sprintf("%s?access_token=%s&agentid=%s", CreateMenuURL, token, agentid)

	var body []byte
	body, err = commons.HTTPGet(url)
	if err != nil {
		return nil, err
	}
	var resp commons.CommonError
	err = json.Unmarshal(body, &resp)
	if err != nil {
		return nil, err
	}
	// 出错返回码，为0表示成功，非0表示调用失败
	if resp.ErrCode != 0 {
		err = fmt.Errorf("DeleteMenu error : errcode=%v , errormsg=%v", resp.ErrCode, resp.ErrMsg)
		return nil, err
	}
	return &resp, nil
}
